
#ifndef _CIRC_BUF_H_
#define _CIRC_BUF_H_

#include "i386.h"




#define CB_OVERRUN -1
#define CB_UNDERRUN -2

#define N_BUFS 1024
#define CB_MASK (N_BUFS-1)

#define _cb_next(_x) ((1+_x)&CB_MASK)

typedef struct {
	word rd;				// 0
	word wr;				// 1
	word n_rd;				// 2
	word n_wr;				// 3
	word id;				// 4
	word n_ur;				// 5
	word n_or;				// 6
	word __pad__[9];			// 7-15
	float buffers[N_BUFS][AUDIOBUF_SZ];
} circbuf_t;



static inline int cb_writebuf(circbuf_t* cb, float* data) {
	register int i;
	if((cb->n_wr-cb->n_rd)>=N_BUFS) {
		/* OVERRUN ! */
		/*printf("OVERRUN !\n");*/
		cb->n_or++;
		return CB_OVERRUN;
	}
	for(i=0;i<AUDIOBUF_SZ;i++) {
		cb->buffers[cb->wr][i] = data[i];
	}
	cb->wr = _cb_next(cb->wr);
	cb->n_wr++;
	return 0;
}


static inline int cb_readbuf(circbuf_t* cb, float** data) {
	if(cb->n_rd>=cb->n_wr) {
		/* UNDERRUN ! */
		/*printf("UNDERRUN !\n");*/
		cb->n_ur++;
		return CB_UNDERRUN;
	}
	*data = cb->buffers[cb->rd];
	cb->rd = _cb_next(cb->rd);
	cb->n_rd++;
	return 0;
}



static inline int cb_delay_samples(circbuf_t* cb) {
	return (cb->n_wr-cb->n_rd)*AUDIOBUF_SZ;

}

#endif

